package com.dalonedrow.engine.ui.impl.border;

import com.dalonedrow.engine.sprite.base.SimpleVector3;
import com.dalonedrow.engine.sprite.base.SpriteBase;
import com.dalonedrow.engine.sprite.base.SpriteImageObject;
import com.dalonedrow.engine.sprite.base.SpriteImageObjectFactory;
import com.dalonedrow.engine.sprite.impl.BasicLineSpriteObject;
import com.dalonedrow.engine.sprite.impl.BasicQuadSpriteObject;
import com.dalonedrow.engine.sprite.impl.BasicSpriteObject;
import com.dalonedrow.engine.sprite.impl.GroupOfImages;
import com.dalonedrow.engine.sprite.impl.GroupOfLines;
import com.dalonedrow.engine.sprite.impl.GroupOfText;
import com.dalonedrow.engine.systems.GameFont;
import com.dalonedrow.engine.systems.JOGLErrorHandler;
import com.dalonedrow.engine.systems.Render;
import com.dalonedrow.engine.ui.base.GuiComponent;
import com.dalonedrow.engine.ui.base.GuiComponentLibrary;
import com.dalonedrow.engine.ui.base.border.GuiBorder;
import com.dalonedrow.globalvariables.constants.hq.GlobalConstants;

/**
 * A simple border, similar to those found in the early 90's SNES games.
 * @author Donald
 */
public final class TextBorder extends GuiBorder {
	/** the border group. */
	private GroupOfImages	borders;
	/** the reference id of the {@link GameFont} used. */
	private int				fontRefId;
	/** the middle sprite. */
	private GroupOfLines	lines;
	/** the middle sprite. */
	private SpriteBase		middle;
	/** the x-offset for the middle graphic. */
	private int				middleInsetX;
	/** the y-offset for the middle graphic. */
	private int				middleInsetY;
	/** the text displayed. */
	private byte[]			text	= new byte[0];
	/** the group of sprites set to render the text. */
	private GroupOfText		textGroup;
	/** Creates a new instance of {@link TextBorder}. */
	public TextBorder() {
		final int thirteen = 13, four = 4, eight = 8;
		super.setInsets(
				thirteen,
				eight,
				eight,
				eight
				);
		try {
			if ("namco_13" != null
					&& "" != null) {
				fontRefId =
						GameFont.getInstance().getFontReferenceId("namco_13");
				text = "".getBytes();
				textGroup = new GroupOfText();
				textGroup.setFontRefId(fontRefId);
				super.setId(GuiComponentLibrary.getInstance().getNextId());
				textGroup.setParentRefId(super.getId());
			}
		} catch (Exception ex) {
			JOGLErrorHandler.getInstance().fatalError(ex);
		}
		GuiComponentLibrary.getInstance().addComponent(this);
	}
	/** Positions all sprites for the border. */
	private void positionSprites() {
		final int three = 3, four = 4, eight = 8, thirteen = 13;
		if (super.getPosition() != null) {
			lines.setPosition(
					super.getPosition().getX(),
					super.getPosition().getY(),
					super.getPosition().getZ()
					);
			lines.clearFloatStore();
			middle.setPosition(
					super.getPosition().getX() + middleInsetX,
					super.getPosition().getY() + middleInsetY,
					super.getPosition().getZ()
							+ GlobalConstants.CHILD_STEP * 0.1f
					);
			middle.clearFloatStore();
			borders.setPosition(
					super.getPosition().getX(),
					super.getPosition().getY(),
					super.getPosition().getZ()
							+ GlobalConstants.CHILD_STEP * 0.2f
					);
			borders.clearFloatStore();
			// DO NOT INCLUDE BORDER POSITION WITH TEXTGROUP POSITION
			// BORDER POSITION WILL BE FACTORED IN WHEN FULL STATS ARE 
			// COMPUTED IN COM.DALONEDROW.JOGL.ENGINE.SPRITE.JAVA
			textGroup.setPosition(
					eight,
					super.getPreferredSize().height
							- thirteen,
					super.getPosition().getZ()
							+ GlobalConstants.CHILD_STEP * 0.3f
					);
			textGroup.clearFloatStore();
		}
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public void prepareForRendering() throws Exception {
		Render.getInstance().registerEntity(borders);
		Render.getInstance().registerEntity(middle);
		Render.getInstance().registerEntity(lines);
		Render.getInstance().registerEntity(textGroup);
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public void setPosition(final double x, final double y, final double z) {
		super.setPosition(x, y, z);
		positionSprites();
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public void setPreferredSize(final int width, final int height) {
		super.setPreferredSize(width, height);
		try {
			final int three = 3, four = 4, five = 5, six = 6, seven = 7, 
					eight = 8;
			SpriteImageObject imgBL =
					SpriteImageObjectFactory.getInstance().getImageByName(
							"vx_border_bl");
			SpriteImageObject imgBR =
					SpriteImageObjectFactory.getInstance().getImageByName(
							"vx_border_br");
			SpriteImageObject imgB =
					SpriteImageObjectFactory.getInstance().getImageByName(
							"vx_border_b");
			SpriteImageObject imgTL =
					SpriteImageObjectFactory.getInstance().getImageByName(
							"vx_border_tl");
			SpriteImageObject imgTR =
					SpriteImageObjectFactory.getInstance().getImageByName(
							"vx_border_tr");
			SpriteImageObject imgT =
					SpriteImageObjectFactory.getInstance().getImageByName(
							"vx_border_t");
			SpriteImageObject imgL =
					SpriteImageObjectFactory.getInstance().getImageByName(
							"vx_border_l");
			SpriteImageObject imgR =
					SpriteImageObjectFactory.getInstance().getImageByName(
							"vx_border_r");
			if (borders == null) {
				borders = new GroupOfImages();
				// sprite images don't get set until the preferred size is set
				middleInsetX = imgL.getWidth() / 2;
				middleInsetY = imgB.getHeight() / 2;

				{ // bottom left
					BasicSpriteObject sb = new BasicSpriteObject();
					sb.setImageRefId(imgBL.getRefId());
					sb.setWidth(imgBL.getWidth());
					sb.setHeight(imgBL.getHeight());
					borders.addImage(sb);
				}
				{ // bottom middle
					BasicSpriteObject sb = new BasicSpriteObject();
					sb.setImageRefId(imgB.getRefId());
					sb.setHeight(imgB.getHeight());
					borders.addImage(sb);
				}
				{ // bottom right
					BasicSpriteObject sb = new BasicSpriteObject();
					sb.setImageRefId(imgBR.getRefId());
					sb.setWidth(imgBR.getWidth());
					sb.setHeight(imgBR.getHeight());
					borders.addImage(sb);
				}
				{ // left
					BasicSpriteObject sb = new BasicSpriteObject();
					sb.setImageRefId(imgL.getRefId());
					sb.setWidth(imgL.getWidth());
					borders.addImage(sb);
				}
				{ // right
					BasicSpriteObject sb = new BasicSpriteObject();
					sb.setImageRefId(imgR.getRefId());
					sb.setWidth(imgR.getWidth());
					borders.addImage(sb);
				}
				{ // top left
					BasicSpriteObject sb = new BasicSpriteObject();
					sb.setImageRefId(imgTL.getRefId());
					sb.setWidth(imgTL.getWidth());
					sb.setHeight(imgTL.getHeight());
					borders.addImage(sb);
				}
				{ // top middle
					BasicSpriteObject sb = new BasicSpriteObject();
					sb.setImageRefId(imgT.getRefId());
					sb.setHeight(imgT.getHeight());
					borders.addImage(sb);
				}
				{ // top right
					BasicSpriteObject sb = new BasicSpriteObject();
					sb.setImageRefId(imgTR.getRefId());
					sb.setWidth(imgTR.getWidth());
					sb.setHeight(imgTR.getHeight());
					borders.addImage(sb);
				}
				{ // middle
					middle = new BasicQuadSpriteObject();
					middle.setRed(GlobalConstants.COL_SNES_BORDER[0]);
					middle.setGreen(GlobalConstants.COL_SNES_BORDER[1]);
					middle.setBlue(GlobalConstants.COL_SNES_BORDER[2]);
					middle.setAlpha(
							GlobalConstants.COL_SNES_BORDER[three]);
					middle.setModRed(GlobalConstants.COL_VX_NO_EDGE[0]);
					middle.setModGreen(GlobalConstants.COL_VX_NO_EDGE[1]);
					middle.setModBlue(GlobalConstants.COL_VX_NO_EDGE[2]);
					middle.setModAlpha(
							GlobalConstants.COL_VX_NO_EDGE[three]);
					middle.assignFlag(
							SpriteBase.FLAG_SPRITE_GRADIENT_VERTICAL_B2T);
				}
				{ // lines
					lines = new GroupOfLines();
					// start 1st line 6px below top
					float x = 2, y = height - 2;
					while (y > 2) {
						BasicLineSpriteObject l = new BasicLineSpriteObject();
						l.setAlpha(0.2f);
						l.setPosition(x, y, 0);
						l.setHeight(1);
						l.setWidth(width - 2);
						lines.addImage(l);
						y -= 2;
					}
				}
			}
			// set bottom-left position
			borders.getImage(0).setPosition(new SimpleVector3(0, 0, 0));
			// set bottom position and width
			borders.getImage(1).setWidth(
					width - imgBL.getWidth() - imgBR.getWidth());
			borders.getImage(1).setPosition(
					new SimpleVector3(imgBL.getWidth(), 0, 0));
			// set bottom-right position
			borders.getImage(2).setPosition(new SimpleVector3(
					width - imgBR.getWidth(), 0, 0));
			// set left position and height
			borders.getImage(three).setHeight(
					height - imgBL.getHeight() - imgTL.getHeight());
			borders.getImage(three).setPosition(
					new SimpleVector3(0, imgBL.getHeight(), 0));
			// set right position and height
			borders.getImage(four).setHeight(
					height - imgBR.getHeight() - imgTR.getHeight());
			borders.getImage(four).setPosition(
					new SimpleVector3(width - imgR.getWidth(), imgBR.getHeight(), 0));
			// set top-left position
			borders.getImage(five).setPosition(
					new SimpleVector3(0, height - imgTL.getHeight(), 0));
			// set top position and width
			borders.getImage(six).setWidth(
					width - imgTL.getWidth() - imgTR.getWidth());
			borders.getImage(six)
					.setPosition(
							new SimpleVector3(imgTL.getWidth(), height
									- imgT.getHeight(), 0));
			// set top-right position
			borders.getImage(seven).setPosition(
					new SimpleVector3(width - imgTR.getWidth(),
							height - imgTR.getHeight(), 0));
			// set middle position and width
			middle.setWidth(width - imgL.getWidth() / 2 - imgR.getWidth() / 2);
			middle.setHeight(height - imgB.getHeight() / 2 - imgT.getHeight()
					/ 2);

			positionSprites();
			imgTL = null;
			imgT = null;
			imgTR = null;
			imgL = null;
			imgR = null;
			imgBL = null;
			imgB = null;
			imgBR = null;
		} catch (Exception ex) {
			JOGLErrorHandler.getInstance().fatalError(ex);
		}
	}
	public final void setText(final String newText) {
		if (super.isDebug()) {
			System.out.println(this.getClass().getSimpleName() + ".setText(*"
					+ newText + "* length "
					+ newText.getBytes().length);
		}
		text = newText.getBytes();
		textGroup.clearLines();
		try {
			textGroup.addLine(
					newText.length() * 11,
					GuiComponent.LEFT,
					newText
					);
		} catch (Exception ex) {
			JOGLErrorHandler.getInstance().fatalError(ex);
		}
	}
}
